package com.html5.weather;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONException;


import com.google.appengine.repackaged.org.json.JSONObject;
import com.html5.utils.Utils;

public class GetWeather {

	private String url = "http://www.google.com/ig/api?hl=en&weather=";

	private String currentWeatherXPath = "//xml_api_reply/weather/current_conditions";

	private String forecastWeatherXPath = "//xml_api_reply/weather/forecast_conditions";

	private Map<String, Document> mapDocument = new HashMap<String, Document>();

	private static GetWeather getWeather = null;

	/**
	 * ��ȡ�����ʵ��-����ģʽ �����ظ�ʵ�����
	 * 
	 * @return
	 */
	public static GetWeather instance() {
		if (getWeather != null) {
			return getWeather;
		} else {
			getWeather = new GetWeather();
			getWeather.resetObj();
			return getWeather;
		}
	}

	/**
	 * ���캯��˽�л�
	 */
	private GetWeather() {
	}

	/**
	 * ˢ������ʵ��
	 */
	private void resetObj() {
		Timer timer = new Timer();
		Task task = new Task();
		// 30����ˢ��һ�����
		timer.schedule(task, 1000 * 60 * 30);
	}

	/**
	 * ��ǰ����״��
	 * 
	 * @param city
	 *            ��������д
	 * @return Map[״̬,���϶�,���϶�,ʪ��,ͼ��,�������]condition temp_f temp_c humidity icon wind_condition
	 * @throws IOException 
	 * @throws com.google.appengine.repackaged.org.json.JSONException 
	 */
	public Map<String, String> getCurrentWeather(JSONObject json) throws IOException, com.google.appengine.repackaged.org.json.JSONException {
		String city=json.getString("param");
		String hl=json.getString("hl");
		if (mapDocument.get("city") == null) {
			mapDocument.put(city, parse(getUrl(hl) + city));
		}
		return getCurrentWeather(mapDocument.get(city));
	}
	
	public String getUrl(String hl){
		return "http://www.google.com/ig/api?hl="+hl+"&weather=";
	}
	/**
	 * ��������������
	 * 
	 * @param city
	 *            ��������д
	 * @return List > Map[����,�������,�������,ͼ��,״̬]day_of_week,low,high,icon,condition
	 * @throws IOException 
	 * @throws com.google.appengine.repackaged.org.json.JSONException 
	 * @throws JSONException 
	 * @throws com.google.appengine.repackaged.org.json.JSONException 
	 */
	public List<Map<String, String>> getForecastWeather(JSONObject jsonObject) throws IOException, com.google.appengine.repackaged.org.json.JSONException {
		String city=jsonObject.getString("param");
		String url=jsonObject.getString("hl");
		if (mapDocument.get("city") == null) {
			mapDocument.put(city, parse(getUrl(url) + city));
		}
		return getForecastWeather(mapDocument.get(city));
	}

	/**
	 * ͨ��URL��ȡһ�� document ����
	 * 
	 * @param url
	 * @return
	 * @throws IOException 
	 * @throws DocumentException
	 * @throws IOException
	 */
	private Document parse(String sURL) throws IOException {
		URL url =  new URL(sURL); 
		InputStream inputStream = url.openStream(); 
		InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gb2312");
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
		String sXml = null;
		Document document = null; 
		try {
			sXml = bufferedReader.readLine();
//			System.out.println(sXml.length()+"xmls");
//			if(sXml.length()<1000){
//				bufferedReader = new BufferedReader(new InputStreamReader(new URL(eURL+"+View").openStream(),"gb2312"));
//				sXml=bufferedReader.readLine();
//			}
			document = DocumentHelper.parseText(sXml);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return document;
	}

	/**
	 * ��ȡ��ǰ����
	 * 
	 * @param document
	 * @return Map[״̬,���϶�,���϶�,ʪ��,ͼ��,�������]
	 */
	@SuppressWarnings("unchecked")
	private Map<String, String> getCurrentWeather(Document document) {
		Map<String, String> map = new HashMap<String, String>(); 

		List list2 = document.selectNodes(currentWeatherXPath);

		for (Object obj : list2) {
			Element element = (Element) obj;
			String s1 = element.element("condition").attributeValue("data");
			String s2 = element.element("temp_f").attributeValue("data");
			String s3 = element.element("temp_c").attributeValue("data");
			String s4 = element.element("humidity").attributeValue("data");
			String s5 = element.element("icon").attributeValue("data");
			String s6 = element.element("wind_condition").attributeValue("data");
			map.put("condition", s1);
			map.put("temp_f", s2);
			map.put("temp_c", s3);
			map.put("humidity", s4);
			map.put("icon", s5);
			map.put("wind_condition", s6);
		}

		return map;
	}

	/**
	 * �� google ���� api xml �ļ� ת����List>map[day_of_week,low,high,icon,condition]
	 * 
	 * @param document
	 * @return List<Map<String, String>> <br />
	 *         map[����,�������,�������,ͼ��,״̬]
	 */
	@SuppressWarnings("unchecked")
	private List<Map<String, String>> getForecastWeather(Document document) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		List list2 = document.selectNodes(forecastWeatherXPath);

		for (int j = 0; j < list2.size(); j++) { 
			Element element = (Element) list2.get(j);
			Map<String, String> map = new HashMap<String, String>();
			String s1 = element.element("day_of_week").attributeValue("data");
			String s2 = element.element("low").attributeValue("data");
			String s3 = element.element("high").attributeValue("data");
			String s4 = element.element("icon").attributeValue("data");
			String s5 = element.element("condition").attributeValue("data");
			map.put("day_of_week", s1);
			map.put("low", s2);
			map.put("high", s3);
			map.put("icon", s4);
			map.put("condition", s5);
			map.put("current_date", Utils.GET_CURRENT_DATE(j));

			list.add(map);
		}
		return list;
	}

	private class Task extends TimerTask {
		@Override
		public void run() {
			getWeather = null;
		}
	}

}
